// una funzione virtuale è una funzione mebro dichiarata come virtual in
// una classe base e ridefinita in una classe derivata

// la funzione virtuale contenuta nella classe base definisce una interfaccia

// ogni ridefinizione della funzione virtuale da parte di una classe derivata
// implementa le operazioni da eseguire con riferimento alla classe derivata

// un puntatore alla classe base può puntare a qualsiasi classe derivata dalla base
// quando un puntatore punta ad un ogetto derivato che contiene una funzione virtuale
// il C++ determina quale versione di tale funzione richiamare sulla base
// del tipo di oggetto puntato dal puntatore e questo a run-time
// mentre l'oggetto può cambiare

// una funzione virtuale pura è una funzioen virtuale che non viene definita
// all'interno della classe base



// conversione è un esempio di classe astratta
// la funzione virtuale calcola non è definita in conversione
// solo quando conversione è ereditata da una classe derivata è
// possibile creare un tipo completo

#include <iostream>
using namespace std;

class conversione
{
protected:
double valore1; //valore iniziale
double valore2; //valore convertito
public:
conversione(double i)
{
valore1=i;
}
double prendi_convertito() {return valore2;}
double prendi_iniziale() {return valore1;}

virtual void calcola() =0; // virtuale pura
};



// litri in galloni
class litri_galloni: public conversione
{
public:
litri_galloni(double i): conversione(i) {}
void calcola()
{
valore2=valore1/3.7854;
}
};

// Fahrenheit in Celsius
class faranheit_celsius : public conversione
{
public:
	faranheit_celsius (double i) : conversione(i) {}
void calcola()
{
valore2=(valore1-32)/1.8;
}
};

int main()
{
conversione *p; // puntatore alla classe base

litri_galloni lgob(4);
faranheit_celsius fcob(32);

// per la conversione usa una funzione virtuale
p=&lgob;
cout<<p->prendi_iniziale()<< " litri sono ";
p->calcola();
cout <<p->prendi_convertito() <<" galloni \n"; 

p=&fcob;
cout<<p->prendi_iniziale()<< " in gradi fahreneit vale ";
p->calcola();
cout <<p->prendi_convertito() <<" in gradi celsius \n"; 

return 0;
}

/*
4 litri sono 1.05669 galloni
32 in gradi fahreneit vale 0 in gradi celsius
Press any key to continue
*/
